<template>
    <div>
        <div class="toolbar">
          <!--方便开发人员测试-->
<!--            <a-button style="margin-left: 10px;" @click="handleAceEditorChange">JSON</a-button> -->
            <a-button style="margin-left: 10px;" @click="undo">撤消</a-button>
            <a-button style="margin-left: 10px;" @click="redo">重做</a-button>
            <label for="input" class="insert">
                插入图片
                <input
                    id="input"
                    type="file"
                    hidden
                    @change="handleFileChange"
                />
            </label>

            <a-button style="margin-left: 10px;" @click="preview(false)">预览</a-button>
            <a-button style="margin-left: 10px;" @click="save">保存草稿</a-button>
            <a-button style="margin-left: 10px;" @click="clearCanvas">清空模板</a-button>
            <a-button style="margin-left: 10px;" :disabled="!areaData.components.length" @click="compose">组合</a-button>
            <a-button
                style="margin-left: 10px;"
                :disabled="!curComponent || curComponent.isLock || curComponent.component != 'Group'"
                @click="decompose"
            >
                拆分
            </a-button>

            <a-button style="margin-left: 10px;" :disabled="!curComponent || curComponent.isLock" @click="lock">锁定</a-button>
            <a-button style="margin-left: 10px;" :disabled="!curComponent || !curComponent.isLock" @click="unlock">解锁</a-button>
            <a-button style="margin-left: 10px;" @click="preview(true)">截图</a-button>

            <div class="canvas-config">
                <span>模板大小</span>
                <a-input-number style="margin-left: 4px;width: 70px" v-model="canvasStyleData.width"/>
              <span>px</span>
                <span style="font-size: 18px;margin-top: 20px;">*</span>
                <a-input-number style="margin-left: 4px;width: 70px" v-model="canvasStyleData.height"/>
              <span>px</span>
            </div>
            <div class="canvas-config">
                <span>模板比例</span>
              <a-input-number style="margin-left: 4px;width: 70px" v-model.trim="scale" @change="handleScaleChange"></a-input-number> %
            </div>
          <a-button style="margin-left: 30px;" type="primary" v-if="type === 'add'" @click="addTemplate">生成模板</a-button>
          <a-button style="margin-left: 30px;" type="primary" v-if="type === 'edit'" @click="update_template">确认修改</a-button>
        </div>
      <a-modal
          destroyOnClose
          class="addModal"
          v-model='openModal'
          width='350px'
          @ok="generateCard"
          title="新增模板"
          @cancel="handleCancel"
          :confirm-loading="confirmLoading"
      >
        <a-form-model :model="basicForm"  layout="inline" ref="basicFormRef" :rules="rules">
          <a-form-model-item
              label="模板编码"
              prop="code"
              style=""
          >
            <a-input style='width: 200px;height: 32px;' v-model.trim="basicForm.code"></a-input>
          </a-form-model-item>
          <a-form-model-item
              label="模板名称"
              prop="name"
              style=""
          >
            <a-input style='width: 200px;height: 32px;' v-model.trim="basicForm.name"></a-input>
          </a-form-model-item>
        </a-form-model>
      </a-modal>

        <!-- 预览 -->
        <Preview v-if="isShowPreview" :is-screenshot="isScreenshot" @close="handlePreviewChange" />
        <AceEditor v-if="isShowAceEditor" @closeEditor="closeEditor" />
      <div ref="mubanRef" v-show="false">
        <div id="muban">
          <div id="mb" :style="getStyle(this.canvasStyleData01)">
            <template v-for="(item,index) in this.componentData01">
              <div :key="index" v-if="item.key === ''" :style="getStyle(item.style)">{{item.propValue}}</div>
              <div :key="index" v-if="item.key !== '' && item.key !== 'qr' && item.key !== 'img'" :style="getStyle(item.style)">{{item.key}}</div>
              <div :key="index" v-if="item.key !== '' && item.key === 'qr'" :style="getStyle(item.style)">
                <img :id="item.imgId+index" :src="item.propValue.url" style="width: 100%;height: 100%"/>
              </div>
              <div :key="index" v-if="item.key !== '' && item.key === 'img'" :style="getStyle(item.style)">
                <img :id="'img'+index" :src="item.propValue.url" style="width: 100%;height: 100%"/>
              </div>
            </template>
          </div>
        </div>
      </div>
    </div>
</template>

<script>
import generateID from '@/utils/generateID'
import toast from '@/utils/toast'
import { mapState } from 'vuex'
import Preview from '@/components/Editor/Preview'
import AceEditor from '@/components/Editor/AceEditor.vue'
import { commonStyle, commonAttr } from '@/custom-component/component-list'
import eventBus from '@/utils/eventBus'
import {$, accMul, accSub, deepClone, getTimestamp, strToBase} from '@/utils/util'
import changeComponentsSizeWithScale, { changeComponentSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
import {getStyle} from "@/utils/style";
import {get_template_list, save_template, update_template} from "@/services/manage";
import storage from "store";
import {ORGANIZATION_ID, USER_TOKEN} from "@/store/mutation-types";

export default {
    components: { Preview, AceEditor },
    data() {
      var checkCode = (rule, value, callback) => {
        setTimeout(() => {
          const regCode = /^(?!.*[\u4e00-\u9fa5])(?!^\d+(\.\d+)?$)[^\d]*\d*[^\d]*$/
          if (!value) {
            callback(new Error('编码不能为空'))
          } else if (!regCode.test(value)) {
            callback(new Error('编码不能包含中文或纯数字'))
          } else if (regCode.test(value)) {
            return callback()
          }
        }, 300)
      }
        return {
          templateList: [],
          basicForm: {
            code: '',
            name: ''
          },
          canvasStyleData01: {},
          componentData01: [],
          rules: {
            code: [{required: true, validator: checkCode, trigger: 'blur'}],
            name: [{required: true, message: '请输入名称', trigger: 'blur'}],
          },
          isShowPreview: false,
          isShowAceEditor: false,
          timer: null,
          isScreenshot: false,
          scale: 100,
          type: '',//编辑or新增
          templateParam: {},
          openModal: false,
          confirmLoading: false,
        }
    },
    computed:{
      ...mapState([
        'componentData',
        'canvasStyleData',
        'areaData',
        'curComponent',
        'curComponentIndex',
      ])
    },
    created() {
        eventBus.$on('preview', this.preview)
        eventBus.$on('save', this.save)
        eventBus.$on('clearCanvas', this.clearCanvas)

        this.scale = this.canvasStyleData.scale
    },
  mounted() {
    this.type = localStorage.getItem('type')
    this.templateParam = storage.get('templateInfo')?storage.get('templateInfo'):{}
    let title = this.templateParam.name?this.templateParam.name:'模板新增'
    // 设置页签标题
    this.$setPageTitle(`/ledgerManagement/templateAdd`, title);
    this.getTemplateList()
  },
  methods: {
      getStyle,
        handleScaleChange() {
            clearTimeout(this.timer)
            this.timer = setTimeout(() => {
                // 画布比例设一个最小值，不能为 0
                // eslint-disable-next-line no-bitwise
                this.scale = (~~this.scale) || 1
                changeComponentsSizeWithScale(this.scale)
            }, 1000)
        },

        handleAceEditorChange() {
            this.isShowAceEditor = !this.isShowAceEditor
        },
        
        closeEditor() {
            this.handleAceEditorChange()
        },

        lock() {
            this.$store.commit('lock')
        },

        unlock() {
            this.$store.commit('unlock')
        },

        compose() {
            this.$store.commit('compose')
            this.$store.commit('recordSnapshot')
        },

        decompose() {
            this.$store.commit('decompose')
            this.$store.commit('recordSnapshot')
        },

        undo() {
            this.$store.commit('undo')
        },

        redo() {
            this.$store.commit('redo')
        },

        handleFileChange(e) {
            const file = e.target.files[0]
            if (!file.type.includes('image')) {
                toast('只能插入图片')
                return
            }

            const reader = new FileReader()
            reader.onload = (res) => {
                const fileResult = res.target.result
                const img = new Image()
                img.onload = () => {
                    const component = {
                        ...commonAttr,
                        id: generateID(),
                        component: 'Picture',
                        key: 'img',
                        label: '图片',
                        icon: '',
                        propValue: {
                            url: fileResult,
                            flip: {
                                horizontal: false,
                                vertical: false,
                            },
                        },
                        style: {
                            ...commonStyle,
                            position: 'absolute',
                            top: 0,
                            left: 0,
                            width: img.width,
                            height: img.height,
                        },
                    }

                    // 根据画面比例修改组件样式比例 https://github.com/woai3c/visual-drag-demo/issues/91
                    changeComponentSizeWithScale(component)

                    this.$store.commit('addComponent', { component })
                    this.$store.commit('recordSnapshot')

                    // 修复重复上传同一文件，@change 不触发的问题
                    $('#input').setAttribute('type', 'text')
                    $('#input').setAttribute('type', 'file')
                }

                img.src = fileResult
            }

            reader.readAsDataURL(file)
        },

        preview(isScreenshot) {
            this.isScreenshot = isScreenshot
            this.isShowPreview = true
            this.$store.commit('setEditMode', 'preview')
        },

        save() {
          localStorage.setItem('canvasData', JSON.stringify(this.componentData))
          localStorage.setItem('canvasStyle', JSON.stringify(this.canvasStyleData))
          this.$message.success('保存成功',1)
        },
        update_template() {
          if (this.componentData.length<=0) {
            this.$message.warning('模板不能为空',1)
            return;
          }
          localStorage.setItem('canvasData', JSON.stringify(this.componentData))
          localStorage.setItem('canvasStyle', JSON.stringify(this.canvasStyleData))
          this.canvasStyleData01 = deepClone(this.canvasStyleData)
          this.canvasStyleData01.width = accMul(accMul(this.canvasStyleData01.width,this.canvasStyleData01.scale),0.01)
          this.canvasStyleData01.height = accMul(accMul(this.canvasStyleData01.height,this.canvasStyleData01.scale),0.01)
          delete this.canvasStyleData01['scale']
          this.componentData01 = deepClone(this.componentData)
          this.componentData01.forEach(item => {
            if (item.component === 'Picture') {
              item.style.top = accSub(item.style.top,accMul(accMul(this.scale,0.01),5))
            }
          })
          this.$nextTick(() => {
            const html = this.$refs.mubanRef.querySelector('#muban').innerHTML
            const htmlBase64 = strToBase(html)
            const userToken = storage.get(USER_TOKEN)
            const timeStamp = getTimestamp()
            const param = {'data': Object.assign({},this.templateParam,{'value': htmlBase64, 'canvas_data': JSON.stringify(this.componentData), 'canvas_style': JSON.stringify(this.canvasStyleData)}),
              'organization_id': storage.get(ORGANIZATION_ID),
              'template_type': 1,
              'hearders': { 'Authorization': userToken, 'Timestamp': timeStamp }}
            return new Promise(resolve => {
              update_template(param)
                  .then(res => {
                    if (res && res.data.code && res.data.code === '1000') {
                      this.$message.success('成功',1)
                    } else {
                      this.$message.error('失败', 1)
                    }
                    resolve()
                  })
                  .catch(err => {
                    console.log(err)
                    this.$message.error('失败', 1)
                    resolve()
                  })
            })
          })
        },
        generateCard() {
          if (this.componentData.length<=0) {
            this.$message.warning('模板不能为空',1)
            this.handleCancel()
            return;
          }
          if (this.templateList.length>0 && this.templateList.find(item => item.code === this.basicForm.code || item.name === this.basicForm.name)) {
            this.$message.warning('该模板编码已存在',1)
            // this.handleCancel()
            return;
          }
          this.confirmLoading = true
          localStorage.setItem('canvasData', JSON.stringify(this.componentData))
          localStorage.setItem('canvasStyle', JSON.stringify(this.canvasStyleData))
          this.canvasStyleData01 = deepClone(this.canvasStyleData)
          this.canvasStyleData01.width = accMul(accMul(this.canvasStyleData01.width,this.canvasStyleData01.scale),0.01)
          this.canvasStyleData01.height = accMul(accMul(this.canvasStyleData01.height,this.canvasStyleData01.scale),0.01)
          delete this.canvasStyleData01['scale']
          this.componentData01 = deepClone(this.componentData)
          this.componentData01.forEach(item => {
            if (item.component === 'Picture') {
              item.style.top = accSub(item.style.top,accMul(accMul(this.scale,0.01),5))
            }
          })
          this.$nextTick(() => {
            const html = this.$refs.mubanRef.querySelector('#muban').innerHTML
            const htmlBase64 = strToBase(html)
            const userToken = storage.get(USER_TOKEN)
            const timeStamp = getTimestamp()
            const param = {'data': Object.assign({},this.basicForm,{'value': htmlBase64, 'canvas_data': JSON.stringify(this.componentData), 'canvas_style': JSON.stringify(this.canvasStyleData)}),
              'organization_id': storage.get(ORGANIZATION_ID),
              'template_type': 1,
              'hearders': { 'Authorization': userToken, 'Timestamp': timeStamp }}
            this.$refs.basicFormRef.validate((valid) => {
              if(valid) {
                return new Promise(resolve => {
                  save_template(param)
                      .then(res => {
                        if (res && res.data.code && res.data.code === '1000') {
                          this.$message.success('成功',1)
                          this.handleCancel()
                        } else {
                          this.$message.error('失败', 1)
                        }
                        this.confirmLoading = false
                        resolve()
                      })
                      .catch(err => {
                        console.log(err)
                        this.$message.error('失败', 1)
                        this.confirmLoading = false
                        resolve()
                      })
                })
              } else {
                this.$message.warning('请检查信息',1)
              }
              this.confirmLoading = false
            })
          })
        },
        addTemplate() {
          this.openModal = true
        },
        handleCancel() {
          this.openModal = false
          this.basicForm = {
            code: '',
            name: ''
          }
          this.$nextTick(() => {
            this.$refs.basicFormRef.clearValidate()
          })
        },
      // 获取所有模板信息
      getTemplateList(){
        const params = Object.assign({},{'organization_id': storage.get(ORGANIZATION_ID)})
        return new Promise(resolve => {
          get_template_list(params).then(({data: res}) => {
            if (res.code === '1000'){
              this.templateList = []
              this.templateList = res.data
            } else if (res.code === '1002') {
              this.templateList = []
            }
            resolve()
          })
              .catch(err => {
                console.log(err)
                this.templateList = []
                resolve()
              })
        })
      },
        clearCanvas() {
          localStorage.removeItem('canvasData')
          localStorage.removeItem('canvasStyle')
          this.$store.commit('setCurComponent', { component: null, index: null })
          this.$store.commit('setComponentData', [])
          this.$store.commit('recordSnapshot')
        },

        handlePreviewChange() {
            this.isShowPreview = false
            this.$store.commit('setEditMode', 'edit')
        },
    },
}
</script>
<style scoped lang="less">
/deep/ .ant-form-inline .ant-form-item-with-help{
  margin-bottom: 0px;
}
</style>
<style lang="scss" scoped>
.toolbar {
    padding: 15px 10px;
    white-space: nowrap;
    overflow-x: auto;
    background: #fff;
    border-bottom: 1px solid #ddd;

    .canvas-config {
        display: inline-block;
        margin-left: 10px;
        font-size: 14px;
        color: #606266;

        input {
            width: 50px;
            margin-left: 4px;
            outline: none;
            padding: 0 5px;
            border: 1px solid #ddd;
            color: #606266;
        }

        span {
            margin-left: 5px;
        }
    }

    .insert {
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        background: #fff;
        border: 1px solid #dcdfe6;
        color: #606266;
        appearance: none;
        text-align: center;
        box-sizing: border-box;
        outline: 0;
        margin: 0;
        transition: .1s;
        font-weight: 500;
        padding: 9px 15px;
        font-size: 12px;
        border-radius: 3px;
        margin-left: 10px;

        &:active {
            color: #3a8ee6;
            border-color: #3a8ee6;
            outline: 0;
        }

        &:hover {
            background-color: #ecf5ff;
            color: #3a8ee6;
        }
    }
}
</style>
